import positionIcon from '@/assets/png/positionfill.png';
import mapHelper from '@/utils/mapHelper';
import AMapLoader from '@amap/amap-jsapi-loader';
type LineOption = {
  showDir?: boolean;
  strokeWeight?: number;
};
type IninitOption = {
  domId: string;
};
type LoadOption = {
  zoom?: number;
  center?: number[];
  plugins?: string[];
  labelLayerProps?: {
    collision?: boolean;
    [key: string]: any;
  };
};
type LatLng = {
  lat: number;
  lng: number;
};
const drawOptions = {
  strokeColor: '#FF33FF',
  strokeWeight: 2,
  strokeOpacity: 0.2,
  fillOpacity: 0.4,
  fillColor: '#1791fc',
  bubble: true,
};
export default class Map {
  domId: string = '';
  aMap: any = null;
  mapInstance: any = null;
  mouseTool: any = null;
  labelsLayer: any = null;
  infoWindow: any = null;
  constructor(options: IninitOption) {
    const { domId } = options;
    this.domId = domId;
  }
  load(options?: LoadOption) {
    let plugins: string[] | undefined = [],
      zoom: number | undefined = 5,
      center: number[] | undefined = [88.210228, 44.136205],
      labelLayerProps: any = { collision: false };
    if (options) {
      plugins = options.plugins;
      zoom = options.zoom;
      center = options.center;
      labelLayerProps = options.labelLayerProps;
    }
    return new Promise((resolve, reject) => {
      AMapLoader.load({
        key: '31d370c0725cb95687da1e187a3061b7',
        version: '2.0',
        plugins,
      })
        .then((AMapInstance) => {
          const mapInstance = new AMapInstance.Map(this.domId, {
            zoom,
            center,
          });
          this.aMap = AMapInstance;
          this.mapInstance = mapInstance;
          // 添加labelayer 统一管理Labelmarker
          this.labelsLayer = new AMapInstance.LabelsLayer({
            collision: false,
            ...labelLayerProps,
          });
          mapInstance.add(this.labelsLayer);
          resolve({
            AMap: AMapInstance,
            mapInstance,
          });
        })
        .catch((e) => {
          reject(e);
        });
    });
  }
  initMapEventList(
    eventList: { eventName: string; callback: (e: any) => any }[],
  ) {
    for (let i = 0; i < eventList.length; i++) {
      const { eventName, callback } = eventList[i];
      this.mapInstance.on(eventName, callback);
    }
  }
  // 加载图形
  loadCircle(data: { radius: number; center: LatLng }, isFit: boolean) {
    const { radius, center } = data;
    const centerObj = new this.aMap.LngLat(center.lng, center.lat);
    const circle = new this.aMap.Circle({
      center: centerObj,
      radius, //半径
      ...drawOptions,
    });
    this.mapInstance.add(circle);
    if (isFit) {
      this.mapInstance.setFitView(
        [circle], // 覆盖物数组
        false, // 动画过渡到制定位置
      );
    }
    return circle;
  }
  loadRectangle(
    data: { southWest: LatLng; northEast: LatLng },
    isFit: boolean,
  ) {
    const { southWest, northEast } = data;
    const bounds = new this.aMap.current.Bounds(
      new this.aMap.current.LngLat(southWest.lng, southWest.lat),
      new this.aMap.current.LngLat(northEast.lng, northEast.lat),
    );
    const rectangle = new this.aMap.current.Rectangle({
      bounds: bounds,
      ...drawOptions,
    });
    this.mapInstance.add(rectangle);
    if (isFit) {
      this.mapInstance.setFitView(
        [rectangle], // 覆盖物数组
        false, // 动画过渡到制定位置
      );
    }
    return rectangle;
  }
  loadPolygon(path: LatLng[], isFit: boolean) {
    if (!path.length) {
      return;
    }
    const pathArray = path.map((point) => {
      const [tLng, tLat] = mapHelper.wgs84togcj02(point.lng, point.lat);
      return new this.aMap.LngLat(tLng, tLat);
    });
    const polygon = new this.aMap.Polygon({
      path: pathArray,
      ...drawOptions,
    });
    this.mapInstance.add(polygon);
    if (isFit) {
      this.mapInstance.setFitView(
        [polygon], // 覆盖物数组
        false, // 动画过渡到制定位置
      );
    }
    return polygon;
  }
  private _markerClick(e: any, that: any) {
    that.infoWindow.setContent(e.target.content);
    that.infoWindow.open(that.mapInstance, e.target.getPosition());
  }
  private _closeInfoWindow(that: any) {
    that.infoWindow.close();
  }
  //加载图标
  loadLabelMarker(data: {
    lat: number;
    lng: number;
    title?: string;
    image?: string;
    size?: number[];
    addToLabelLayer?: boolean;
    showInfoWindow?: boolean;
    infoWindowContent?: string;
  }) {
    const {
      lat,
      lng,
      title,
      image,
      size,
      addToLabelLayer = true,
      showInfoWindow = false,
      infoWindowContent,
    } = data;
    const [tLng, tLat] = mapHelper.wgs84togcj02(lng, lat);
    let text;
    if (title) {
      text = {
        // 要展示的文字内容
        content: title,
        // 文字方向，有 icon 时为围绕文字的方向，没有 icon 时，则为相对 position 的位置
        direction: 'bottom',
        // 在 direction 基础上的偏移量
        // offset: [-32, -16],
        // 文字样式
        style: {
          // 字体大小
          fontSize: 12,
          // 字体颜色
          fillColor: '#22886f',
          // 描边颜色
          strokeColor: '#fff',
          // 描边宽度
          strokeWidth: 2,
        },
      };
    }
    const icon = {
      type: 'image',
      image: image ? image : positionIcon,
      size: size ? size : [32, 32],
    };
    const marker = new this.aMap.LabelMarker({
      offset: new this.aMap.Pixel(-10, -10),
      position: new this.aMap.LngLat(tLng, tLat),
      icon,
      text,
    });
    // 鼠标移动到图标上展示信息窗口，移出关闭
    if (showInfoWindow && infoWindowContent) {
      if (!this.infoWindow) {
        this.infoWindow = new this.aMap.InfoWindow({
          offset: new this.aMap.Pixel(0, -30),
        });
      }
      marker.content = infoWindowContent;
      marker.on('click', (e: any) => {
        this._markerClick(e, this);
      });
      // marker.on('mouseout', () => {
      //   this._closeInfoWindow(this);
      // });
    }
    if (addToLabelLayer) {
      this.labelsLayer.add(marker);
    } else {
      this.mapInstance.add(marker);
    }
    return marker;
  }
  loadLine(data: LatLng[], options: LineOption) {
    const path: any[] = [];
    data.forEach((item) => {
      const { lat, lng } = item;
      const [tLng, tLat] = mapHelper.wgs84togcj02(lng, lat);
      path.push(new this.aMap.LngLat(tLng, tLat));
    });
    const polyline = new this.aMap.Polyline({
      path: path,
      strokeWeight: 2, //线条宽度
      strokeColor: 'blue', //线条颜色
      lineJoin: 'round', //折线拐点连接处样式
      ...options,
    });
    this.mapInstance.add(polyline);
    return polyline;
  }
  // 图形绘制
  handleDrawCircleEvent(event: any) {
    const center = event.obj.getCenter();
    const radius = event.obj.getRadius();
    const wgs84Center = mapHelper.gcj02towgs84(center.lng, center.lat);
    return {
      ...event,
      type: 'circle',
      points: wgs84Center.join(','),
      radius,
    };
  }
  handleDrawRectangleEvent(event: any) {
    const bounds = event.obj.getBounds();
    const { northEast, southWest } = bounds;
    const [wgs84NorthLng, wgs84NorthLat] = mapHelper.gcj02towgs84(
      northEast.lng,
      northEast.lat,
    );
    const [wgsSouthLng, wgsSouthLat] = mapHelper.gcj02towgs84(
      southWest.lng,
      southWest.lat,
    );
    return {
      ...event,
      points: `${wgs84NorthLng},${wgs84NorthLat};${wgsSouthLng},${wgsSouthLat}`,
      type: 'rectangle',
      radius: null,
    };
  }
  handleDrawPolygonEvent(event: any) {
    const path = event.obj.getPath();
    const points = path.map((latLng: LatLng) => {
      const [lng, lat] = mapHelper.gcj02towgs84(latLng.lng, latLng.lat);
      return `${lng},${lat}`;
    });
    return {
      ...event,
      points: points.join(';'),
      type: 'polygon',
      radius: null,
    };
  }
  enableDrawCircle(callback: (e: any) => any) {
    // 将上次的图形绘制关闭并清空
    if (this.mouseTool) {
      this.mouseTool.close(true);
      this.mouseTool = null;
    }
    this.mouseTool = new this.aMap.MouseTool(this.mapInstance);
    this.mouseTool.circle(drawOptions);
    this.mouseTool.on('draw', (event: any) => {
      this.mouseTool.close();
      const res = this.handleDrawCircleEvent(event);
      callback(res);
    });
  }
  enableDrawRectangle(callback: (e: any) => any) {
    if (this.mouseTool) {
      this.mouseTool.close(true);
      this.mouseTool = null;
    }
    this.mouseTool = new this.aMap.MouseTool(this.mapInstance);
    this.mouseTool.rectangle(drawOptions);
    this.mouseTool.on('draw', (event: any) => {
      this.mouseTool.close();
      const res = this.handleDrawRectangleEvent(event);
      callback(res);
    });
  }
  enableDrawPolygon(callback: (e: any) => any) {
    if (this.mouseTool) {
      this.mouseTool.close(true);
      this.mouseTool = null;
    }
    this.mouseTool = new this.aMap.MouseTool(this.mapInstance);
    this.mouseTool.polygon(drawOptions);
    this.mouseTool.on('draw', (event: any) => {
      this.mouseTool.close();
      this.mouseTool.close();
      const res = this.handleDrawPolygonEvent(event);
      callback(res);
    });
  }
  setZoomAndCenter(zoom: number, center: LatLng) {
    this.mapInstance.setZoomAndCenter(
      zoom,
      new this.aMap.LngLat(center.lng, center.lat),
    );
  }
  remove(shape: any) {
    this.mapInstance.remove(shape);
  }
  destroy() {
    this.mapInstance.destroy();
  }
  clear() {
    this.mapInstance.clearMap();
  }
}
